package org.jeecg.modules.mes.produce.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.mes.chiefdata.entity.MesChiefdataBomitem;
import org.jeecg.modules.mes.chiefdata.entity.MesChiefdataProductline;
import org.jeecg.modules.mes.chiefdata.entity.MesMaterielPcb;
import org.jeecg.modules.mes.client.StockClient;
import org.jeecg.modules.mes.client.SystemClient;
import org.jeecg.modules.mes.produce.entity.*;
import org.jeecg.modules.mes.produce.mapper.MesCourseScanMapper;
import org.jeecg.modules.mes.produce.service.*;
import org.jeecg.modules.mes.storage.entity.MesStorageWholesale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description: 订单管理-线程扫描
 * @Author: jeecg-boot
 * @Date: 2020-12-24
 * @Version: V1.0
 */
@Service
public class MesCourseScanServiceImpl extends ServiceImpl<MesCourseScanMapper, MesCourseScan> implements IMesCourseScanService {


    @Autowired
    private IMesCommandbillPitemService mesCommandbillPitemService;
    @Autowired
    private IMesCommandbillInfoService mesCommandbillInfoService;
    @Autowired
    private IBindingRecordInfoService bindingRecordInfoService;
    /**
     * 物料追踪记录表
     */
    @Autowired
    private IMesCourseScanLogService mesCourseScanLogService;

    @Autowired
    SystemClient systemClient;
    @Autowired
    StockClient stockClient;
    @Autowired
    RedisUtil redisUtil;

    private ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * 订单管理-线程扫描-添加
     */
    @Override
    @Transactional
    public boolean mainAdd(MesCourseScan mesCourseScan) {
        long startTime = System.currentTimeMillis();
        String commandCode = mesCourseScan.getCommandCode();//制令单编码
        String scanContent = mesCourseScan.getScanContent();//扫描内容
        String batchNum = mesCourseScan.getBatchNum();//批次数量
//        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        QueryWrapper<MesCommandbillInfo> commandbillInfoWrapper = new QueryWrapper<>();
        commandbillInfoWrapper.eq("commandbill_code", commandCode);
        MesCommandbillInfo commandbillInfo = mesCommandbillInfoService.getOne(commandbillInfoWrapper);

        if (StringUtils.isNotBlank(commandCode)) {//制令单号
            QueryWrapper<MesCourseScan> wrapper = new QueryWrapper<>();//通过制令单号，查询相关的线程扫描数据
            wrapper.eq("command_code", commandCode);
            wrapper.last("limit 10");
            List<MesCourseScan> courseScanList = this.list(wrapper);
            if (courseScanList.size() != 0) {

                //通过制令单号找到的数据行数 = 机器上料的板数
//                BigDecimal listSize = new BigDecimal(courseScanList.size());
//                System.err.println(courseScanList.size());


                //todo 物料预警需改为异步执行
                if (commandbillInfo != null) {
                    //BigDecimal requireNum = new BigDecimal(commandbillInfo.getPlantNum());//计划数量
                    String remindRate = commandbillInfo.getGlazeRemind();//上料提醒比例
                    remindRate = remindRate.substring(0, remindRate.length() - 1);  //去掉“%”
                    BigDecimal rate = new BigDecimal(remindRate);
                    BigDecimal remind = rate.divide(new BigDecimal(100), 3, RoundingMode.HALF_UP);//除以100，获取小数值

                    //通过制令单号，获取制令单BOM的数据
                    QueryWrapper<MesCommandbillPitem> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("commandbill_code", commandCode);
                    List<MesCommandbillPitem> commandbillPitemList = mesCommandbillPitemService.list(wrapper2);
                    if (commandbillPitemList.size() != 0) {
                        //制令单bom数据
                        for (MesCommandbillPitem commandbillPitem : commandbillPitemList) {
                            //未上料完的情况下，判断是否需要发料提醒
                            String unglazeNum = commandbillPitem.getUnglazeNum();
                            if (!commandbillPitem.getDeliveryNum().equals(unglazeNum)) {
                                BigDecimal ungnum = new BigDecimal(unglazeNum);//已上料数量
                                BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
                                BigDecimal remindNum = ungnum.multiply(remind);//剩余数量 = 已上料数量 * 上料提醒比例
                                BigDecimal reachNum = ungnum.subtract(remindNum);//到达提醒的数量 = 已上料数量 - 剩余数量
                                //System.err.println(reachNum);
                                if (consumeNum.compareTo(reachNum) > -1) {//已消耗数量大于等于到达提醒的数量时提醒上料
                                    //调用上料提醒接口
                                    //System.err.println(sysUser.getUsername());
                                    String productName = commandbillInfo.getMechanismName();
                                    //todo 测试时，向当前登录用户发送消息提醒；正式上线后，需要向产线操作人员（溢哲渝设定）发送上料提醒
//                                    systemClient.sendRemindMessage(sysUser.getUsername(), commandCode, "产线" + commandbillInfo.getLineType() + "==" + productName);


                                }
                                //已消耗数量大于等于已上料数量，停机
                                if (consumeNum.compareTo(ungnum) > -1) {
                                    //调用停机接口
                                    //根据制令单bom的产线编号去查询该产线的产线id
                                    String lineType = commandbillInfo.getLineType();//产线编号
                                    MesChiefdataProductline mesChiefdataProductline = systemClient.queryByLineCode(lineType);
                                    if (mesChiefdataProductline != null) {
                                        //停机
                                        systemClient.stopById(mesChiefdataProductline.getId(), "30");
                                    } else {
                                        throw new RuntimeException("产线数据有误，无法停机！请检查！");
                                    }
                                }
                            }
                        }
                    }
                } else {
                    throw new RuntimeException("找不到制令单信息！请检查");
                }
            }
        }
        long startTime1 = System.currentTimeMillis();
        QueryWrapper<MesCourseScan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("command_code", commandCode);
        queryWrapper.eq("scan_content", scanContent);
        MesCourseScan courseScan = this.getOne(queryWrapper);
        if (courseScan == null) {
            String sjnumstr = "1";//连扳数默认为1
            BigDecimal lbsnum = new BigDecimal(sjnumstr);
            //制令单信息不为空
            if (commandbillInfo != null) {
                //通过制令单号，获取制令单BOM的数据
                QueryWrapper<MesCommandbillPitem> wrapper = new QueryWrapper<>();
                wrapper.eq("commandbill_code", commandCode);
                List<MesCommandbillPitem> commandbillPitemList = mesCommandbillPitemService.list(wrapper);
                if (commandbillPitemList.size() != 0) {
//                    int pcbnum=0;
                    MesMaterielPcb pcbinfo = null;
                    //制令单bom数据
                    /*for (MesCommandbillPitem commandbillPitem : commandbillPitemList) {
                        if(StringUtils.isBlank(commandbillPitem.getConsumeNum())){
                            commandbillPitem.setConsumeNum("0");
                        }
                        BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
                        BigDecimal glazeNum = new BigDecimal(commandbillPitem.getUnglazeNum());//已上料数据
                        BigDecimal quantity = new BigDecimal(commandbillPitem.getQuantity());//消耗用量
                        BigDecimal totalNum = consumeNum.add(quantity);//新的消耗数量 = 已消耗数量 + 消耗用量
                        //消耗用量不能大于上料数量
                        if(totalNum.compareTo(glazeNum) == -1){
                            //修改消耗数量
                        }else {
                            throw new RuntimeException("消耗数量超过上料数量！请检查！");
                        }
                        //类型是pcb的物料获取连板数
                        if("PCB".equals(commandbillPitem.getMaterielType())){
                            pcbnum++;
                            pcbinfo=selectByMaterielPcb(commandbillPitem.getMaterielCode());//pcb连板数
                        }
                    }*/
                    List<MesStorageWholesale> mesStorageWholesales = stockClient.selectQuery4SL(commandbillInfo.getId());
                    List<MesCommandbillPitem> commandbillPitems = new ArrayList<MesCommandbillPitem>();
                    List<MesCourseScanLog> courseScanLogs = new ArrayList<MesCourseScanLog>();
                    //smt才需要钢网、刮刀、飞达
                    if ("SMT".equals(commandbillInfo.getProduceGrade())) {
                        //通过制令单号，获取制令单BOM的数据
                        QueryWrapper<MesCommandbillPitem> queryWrapper1 = new QueryWrapper<>();
                        queryWrapper1.eq("commandbill_code", commandCode);
                        queryWrapper1.eq("materiel_type", "PCB");
                        List<MesCommandbillPitem> pcblist = mesCommandbillPitemService.list(queryWrapper1);
                        if (pcblist.size() > 1) {
                            throw new RuntimeException("制令单BOM只能有一个类型为PCB板的物料！请检查！");
                        }
                        //连版数获取
                        if (pcblist.size() != 0) {
                            if (StringUtils.isNotEmpty(pcblist.get(0).getMaterielCode())) {
                                String lbs = (String) redisUtil.hget(CacheConstant.LINE_TYPE_PCB_LBS, pcblist.get(0).getMaterielCode());
                                if (StringUtils.isEmpty(lbs)) {
                                    pcbinfo = selectByMaterielPcb(pcblist.get(0).getMaterielCode());
                                    if (pcbinfo != null && StringUtils.isNotBlank(pcbinfo.getLinkBoard())) {
                                        lbsnum = new BigDecimal(pcbinfo.getLinkBoard());//连板数
                                        //增加缓存pcb连扳数
                                        redisUtil.hset(CacheConstant.LINE_TYPE_PCB_LBS, pcblist.get(0).getMaterielCode(), lbsnum.toString());
                                    }
                                } else {
                                    lbsnum = new BigDecimal(lbs);//连板数
                                }
                            }
                        }
                        //批量不为空的情况下执行乘法
                        if (StringUtils.isNotEmpty(batchNum)) {
                            lbsnum = new BigDecimal(batchNum).multiply(lbsnum);
                        }
                        //判断钢网、刮刀是否绑定
                        QueryWrapper<BindingRecordInfo> bindingqueryWrapper = new QueryWrapper<BindingRecordInfo>();
                        bindingqueryWrapper.eq("commandbill_code", commandCode).eq("state", "0");
                        List<BindingRecordInfo> list = bindingRecordInfoService.list(bindingqueryWrapper);
                        boolean ifbindgw = true;//钢网是否存在
                        String ifbindgwSn = "";//钢网SN编码
                        boolean ifbindgd = true;//刮刀是否存在
                        String ifbindgdSn = "";//刮刀SN编码
                        for (BindingRecordInfo recordInfo : list) {
                            if ("钢网".equals(recordInfo.getBindingName())) {
                                ifbindgwSn = recordInfo.getBindingSn();
                                ifbindgw = true;
                            }
                            if ("刮刀".equals(recordInfo.getBindingName())) {
                                ifbindgdSn = recordInfo.getBindingSn();
                                ifbindgd = true;
                            }
                        }
                        if (!ifbindgw || !ifbindgd) {
                            //调用停机接口
                            //根据制令单bom的产线编号去查询该产线的产线id
                            String lineType = commandbillInfo.getLineType();//产线编号
                            MesChiefdataProductline mesChiefdataProductline = systemClient.queryByLineCode(lineType);
                            if (mesChiefdataProductline != null) {
                                //停机
                                systemClient.stopById(mesChiefdataProductline.getId(), "30");
                            } else {
                                throw new RuntimeException("产线数据有误，无法停机！请检查！");
                            }
                            throw new RuntimeException("未绑定钢网或刮刀，设备已停机！");
                        }

                        //消耗数量不超过上料数量的时候修改上料
                        for (MesCommandbillPitem commandbillPitem2 : commandbillPitemList) {

                            if (StringUtils.isBlank(commandbillPitem2.getConsumeNum())) {
                                commandbillPitem2.setConsumeNum("0");
                            }
                            BigDecimal consumeNum2 = new BigDecimal(commandbillPitem2.getConsumeNum());//已消耗数量
                            BigDecimal quantity2 = BigDecimal.ZERO;//消耗用量

                            //如果是反面的话
                            if ("反面".equals(mesCourseScan.getQuery3())) {
                                //根据bom去查反面用量，反面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getInverseQuantity())) {
                                    quantity2 = new BigDecimal(getsfg.getInverseQuantity().trim());
                                }
                            } else {
                                //据bom去查正面用量，正面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getQuantity().trim())) {
                                    quantity2 = new BigDecimal(getsfg.getQuantity());
                                }
                            }
                            //用量0跳出循环
                            if (quantity2.equals(BigDecimal.ZERO)) {
                                continue;
                            }
                            String itemid = commandbillPitem2.getId();
                            //过滤其中的上料信息
                            List<MesStorageWholesale> mesStorageWholesaleStream = mesStorageWholesales.stream().filter(f -> f.getBaseCode().equals(itemid)).collect(Collectors.toList());
//                            System.out.println("物料：" + commandbillPitem2.getMaterielCode());
//                            mesStorageWholesaleStream.forEach(System.out::println);
                            if (mesStorageWholesaleStream.size() == 0) {
                                throw new RuntimeException("未找到料号:" + commandbillPitem2.getMaterielCode() + " 的上料信息，请检查！");
                            }

                            BigDecimal sjnum = lbsnum.multiply(quantity2);//实际使用数量=连板数*消耗用量
                            BigDecimal totalNum2 = consumeNum2.add(sjnum);//新的消耗数量 = 已消耗数量 + 实际使用数量
                            if (totalNum2.compareTo(consumeNum2) == -1) {
                                throw new RuntimeException("消耗数量超过上料数量！请检查！");
                            }

                            //修改消耗数量
                            commandbillPitem2.setConsumeNum(totalNum2.toString());
                            commandbillPitems.add(commandbillPitem2);

                            //判定当前使用的是哪个物料
                            Map<String, String> map = getwl(commandbillPitem2, mesStorageWholesaleStream);

                            //新增物料追踪记录，便于后期扫码追踪
                            MesCourseScanLog mesCourseScanLog = new MesCourseScanLog();
                            mesCourseScanLog.setCommandbillId(commandbillPitem2.getCommandbillId());
                            mesCourseScanLog.setCommandbillCode(commandbillPitem2.getCommandbillCode());
                            mesCourseScanLog.setFeederSn(map.get("feederSn"));
                            mesCourseScanLog.setPassage(map.get("passage"));
                            mesCourseScanLog.setStorageId(map.get("glazeId"));
                            mesCourseScanLog.setUnit(map.get("unit"));
                            mesCourseScanLog.setWareCode(map.get("wareCode"));
                            mesCourseScanLog.setWareName(map.get("wareName"));
                            mesCourseScanLog.setWareSite(map.get("wareSite"));
                            mesCourseScanLog.setLineType(commandbillInfo.getLineType());
                            mesCourseScanLog.setQuantity(commandbillPitem2.getQuantity());
                            mesCourseScanLog.setMaterielId(commandbillPitem2.getMaterielId());
                            mesCourseScanLog.setMaterielName(commandbillPitem2.getMaterielName());
                            mesCourseScanLog.setMaterielCode(commandbillPitem2.getMaterielCode());
                            mesCourseScanLog.setPcbId(scanContent);//pcbId
                            courseScanLogs.add(mesCourseScanLog);

                            //菲达使用次数增加
                            if (!"无feeder".equals(map.get("feederSn")) && !(sjnum.compareTo(BigDecimal.ZERO) == 0)) {
                                boolean mark = systemClient.editfeederComitem(map.get("feederSn"), sjnum.toString());
                                System.out.println("feedersn:" + map.get("feederSn") + " sjnum:" + sjnum.toString() + " 状态：" + mark);
                            }
                        }

                        //增加钢网刮刀使用次数
                        systemClient.increaseSteelmeshNum(ifbindgwSn);
                        systemClient.increaseScraperNum(ifbindgdSn);

                        MesStorageWholesale mesStorageWholesale = new MesStorageWholesale();
                        mesStorageWholesale.setBaseRownum(commandbillInfo.getId());
                        mesStorageWholesale.setProductCode(commandbillInfo.getMechanismCode());
                        mesStorageWholesale.setProductName(commandbillInfo.getMechanismName());
                        mesStorageWholesale.setInwareNum(lbsnum.toString());
                        mesStorageWholesale.setUnit("片");
                        mesStorageWholesale.setBaseDockettype("制令单线程扫描");
                        mesStorageWholesale.setQuery5(commandbillInfo.getLineType());//线别
                        mesStorageWholesale.setId(scanContent);
                        executor.execute(new Runnable() {
                            @Override
                            public void run() {
                                //新增批号交易信息，便于后期入库使用  数据量过大，弃用(重新开放，启用线程添加)
                                boolean mark = stockClient.scanCourseadd(mesStorageWholesale);
                                System.out.println("添加制令单扫描结果>>mark>" + mark);
                            }
                        });
                    } else {

                        //消耗数量不超过上料数量的时候修改上料
                        for (MesCommandbillPitem commandbillPitem2 : commandbillPitemList) {

                            if (StringUtils.isBlank(commandbillPitem2.getConsumeNum())) {
                                commandbillPitem2.setConsumeNum("0");
                            }
                            BigDecimal consumeNum2 = new BigDecimal(commandbillPitem2.getConsumeNum());//已消耗数量
                            BigDecimal quantity2 = BigDecimal.ZERO;//消耗用量

                            //如果是反面的话
                            if ("反面".equals(mesCourseScan.getQuery3())) {
                                //根据bom去查反面用量，反面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getInverseQuantity())) {
                                    quantity2 = new BigDecimal(getsfg.getInverseQuantity());
                                }
                            } else {
                                //根据bom去查正面用量，正面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getQuantity())) {
                                    quantity2 = new BigDecimal(getsfg.getQuantity());
                                }
                            }
                            //用量0跳出循环
                            if (quantity2.equals(BigDecimal.ZERO)) {
                                continue;
                            }
                            String itemid = commandbillPitem2.getId();
                            //过滤其中的上料信息
                            List<MesStorageWholesale> mesStorageWholesaleStream = mesStorageWholesales.stream().filter(f -> f.getBaseCode().equals(itemid)).collect(Collectors.toList());
//                            System.out.println("物料：" + commandbillPitem2.getMaterielCode());
//                            mesStorageWholesaleStream.forEach(System.out::println);
                            if (mesStorageWholesaleStream.size() == 0) {
                                throw new RuntimeException("未找到料号:" + commandbillPitem2.getMaterielCode() + " 的上料信息，请检查！");
                            }

                            BigDecimal sjnum = lbsnum.multiply(quantity2);//实际使用数量=连板数*消耗用量
                            BigDecimal totalNum2 = consumeNum2.add(sjnum);//新的消耗数量 = 已消耗数量 + 实际使用数量
                            if (totalNum2.compareTo(consumeNum2) == -1) {
                                throw new RuntimeException("消耗数量超过上料数量！请检查！");
                            }
                            //修改消耗数量
                            commandbillPitem2.setConsumeNum(totalNum2.toString());
                            commandbillPitems.add(commandbillPitem2);
                        }

                    }
                    //有这个bom的情况下新增线程扫描
                    mesCourseScan.setBatchNum(lbsnum.toString());
                    this.save(mesCourseScan);
                    //批量修改消耗数据
                    mesCommandbillPitemService.updateBatchById(commandbillPitems);
                    if (!CollectionUtils.isEmpty(courseScanLogs)) {
                        //批量新增物料追踪记录
                        mesCourseScanLogService.saveBatch(courseScanLogs);
                    }
                    //执行方法
                    long endTime = System.currentTimeMillis();
                    float excTime = (float) (endTime - startTime) / 1000;
                    float excTime1 = (float) (endTime - startTime1) / 1000;
                    System.out.println("执行addSourseScan时间：1区：" + excTime + "s 2区：" + excTime1 + "s");
                } else {
                    throw new RuntimeException("找不到制令单BOM信息！请检查");
                }
            } else {
                throw new RuntimeException("找不到制令单信息！请检查");
            }
        } else {
            throw new RuntimeException("扫描内容重复！请检查");
        }

        if (com.epms.util.ObjectHelper.isNotEmpty(commandbillInfo)) {
            if (com.epms.util.ObjectHelper.isEmpty(commandbillInfo.getProduceState()) || "0".equals(commandbillInfo.getProduceState())) {
                //增加缓存，让aoi拿到使用
                redisUtil.hset(CacheConstant.COMMANDBILL_INFO_LINE_TYPE, commandbillInfo.getLineType(), commandbillInfo.getCommandbillCode());
                //其他所以设置为0未生产
                mesCommandbillInfoService.lambdaUpdate().eq(MesCommandbillInfo::getLineType, commandbillInfo.getLineType()).set(MesCommandbillInfo::getProduceState, "0").update();
                //更新为1生产中
                commandbillInfo.setProduceState("1");//生产状态
                mesCommandbillInfoService.updateById(commandbillInfo);
            }
        } else {
            throw new RuntimeException("找不到制令单信息！请检查");
        }

        return true;
    }

    /**
     * 更新物料消耗数据和其他数据
     *
     * @param mesCourseScan
     */
    public void getxh(MesCourseScan mesCourseScan) {
        System.out.println("================111==================");
        String commandCode = mesCourseScan.getCommandCode();//制令单编码
        String scanContent = mesCourseScan.getScanContent();//扫描内容
        QueryWrapper<MesCourseScan> SSS = new QueryWrapper<>();
        SSS.eq("command_code", commandCode);
        SSS.eq("scan_content", scanContent);
        MesCourseScan courseScanS = this.getOne(SSS);
        if (courseScanS == null) {
            mesCourseScan.setCreateBy("AOI");
            QueryWrapper<MesCommandbillInfo> commandbillInfoWrapper = new QueryWrapper<>();
            commandbillInfoWrapper.eq("commandbill_code", commandCode);
            MesCommandbillInfo commandbillInfo = mesCommandbillInfoService.getOne(commandbillInfoWrapper);

            System.out.println("================222==================");
            //获取旧的数据,没有就不更新
            QueryWrapper<MesCourseScan> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("command_code", commandCode);
            queryWrapper.orderByDesc("create_time");
            queryWrapper.last("limit 1");
            MesCourseScan courseScan = this.getOne(queryWrapper);

            System.out.println("================333==================");
            if (courseScan != null) {

                System.out.println("================444==================");
                String query3 = courseScan.getQuery3();
                mesCourseScan.setQuery3(query3);
                String sjnumstr = "1";//连扳数默认为1
                BigDecimal lbsnum = BigDecimal.ZERO;
                //制令单信息不为空
                if (commandbillInfo != null) {
                    //通过制令单号，获取制令单BOM的数据
                    QueryWrapper<MesCommandbillPitem> wrapper = new QueryWrapper<>();
                    wrapper.eq("commandbill_code", commandCode);
                    List<MesCommandbillPitem> commandbillPitemList = mesCommandbillPitemService.list(wrapper);
                    if (commandbillPitemList.size() != 0) {
                        //                    int pcbnum=0;
                        MesMaterielPcb pcbinfo = null;
                        //制令单bom数据
                            /*for (MesCommandbillPitem commandbillPitem : commandbillPitemList) {
                                if(StringUtils.isBlank(commandbillPitem.getConsumeNum())){
                                    commandbillPitem.setConsumeNum("0");
                                }
                                BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
                                BigDecimal glazeNum = new BigDecimal(commandbillPitem.getUnglazeNum());//已上料数据
                                BigDecimal quantity = new BigDecimal(commandbillPitem.getQuantity());//消耗用量
                                BigDecimal totalNum = consumeNum.add(quantity);//新的消耗数量 = 已消耗数量 + 消耗用量
                                //消耗用量不能大于上料数量
                                if(totalNum.compareTo(glazeNum) == -1){
                                    //修改消耗数量
                                }else {
                                    throw new RuntimeException("消耗数量超过上料数量！请检查！");
                                }
                                //类型是pcb的物料获取连板数
                                if("PCB".equals(commandbillPitem.getMaterielType())){
                                    pcbnum++;
                                    pcbinfo=selectByMaterielPcb(commandbillPitem.getMaterielCode());//pcb连板数
                                }
                            }*/
                        //通过制令单号，获取制令单BOM的数据
                        QueryWrapper<MesCommandbillPitem> queryWrapper1 = new QueryWrapper<>();
                        queryWrapper1.eq("commandbill_code", commandCode);
                        queryWrapper1.eq("materiel_type", "PCB");
                        List<MesCommandbillPitem> pcblist = mesCommandbillPitemService.list(queryWrapper1);
                        if (pcblist.size() > 1) {
                            throw new RuntimeException("制令单BOM只能有一个类型为PCB板的物料！请检查！");
                        }

                        //连版数获取
                        if (pcblist.size() != 0) {
                            if (StringUtils.isNotEmpty(pcblist.get(0).getMaterielCode())) {
                                String lbs = (String) redisUtil.hget(CacheConstant.LINE_TYPE_PCB_LBS, pcblist.get(0).getMaterielCode());
                                if (StringUtils.isEmpty(lbs)) {
                                    pcbinfo = selectByMaterielPcb(pcblist.get(0).getMaterielCode());
                                    if (pcbinfo != null && StringUtils.isNotBlank(pcbinfo.getLinkBoard())) {
                                        lbsnum = new BigDecimal(pcbinfo.getLinkBoard());//连板数
                                        //增加缓存pcb连扳数
                                        redisUtil.hset(CacheConstant.LINE_TYPE_PCB_LBS, pcblist.get(0).getMaterielCode(), lbsnum.toString());
                                    }
                                } else {
                                    lbsnum = new BigDecimal(lbs);//连板数
                                }
                            }
                        }

                        //判断钢网、刮刀是否绑定
                        QueryWrapper<BindingRecordInfo> bindingqueryWrapper = new QueryWrapper<BindingRecordInfo>();
                        bindingqueryWrapper.eq("commandbill_code", commandCode).eq("state", "0");
                        List<BindingRecordInfo> list = bindingRecordInfoService.list(bindingqueryWrapper);
                        boolean ifbindgw = true;//钢网是否存在
                        String ifbindgwSn = "";//钢网SN编码
                        boolean ifbindgd = true;//刮刀是否存在
                        String ifbindgdSn = "";//刮刀SN编码
                        for (BindingRecordInfo recordInfo : list) {
                            if ("钢网".equals(recordInfo.getBindingName())) {
                                ifbindgwSn = recordInfo.getBindingSn();
                                ifbindgw = true;
                            }
                            if ("刮刀".equals(recordInfo.getBindingName())) {
                                ifbindgdSn = recordInfo.getBindingSn();
                                ifbindgd = true;
                            }
                        }
                        if (!ifbindgw || !ifbindgd) {
                            //调用停机接口
                            //根据制令单bom的产线编号去查询该产线的产线id
                            String lineType = commandbillInfo.getLineType();//产线编号
                            MesChiefdataProductline mesChiefdataProductline = systemClient.queryByLineCode(lineType);
                            if (mesChiefdataProductline != null) {
                                //停机
                                systemClient.stopById(mesChiefdataProductline.getId(), "30");
                            } else {
                                throw new RuntimeException("产线数据有误，无法停机！请检查！");
                            }
                            throw new RuntimeException("未绑定钢网或刮刀，设备已停机！");
                        }


                        List<MesStorageWholesale> mesStorageWholesales = stockClient.selectQuery4SL(commandbillInfo.getId());
                        List<MesCommandbillPitem> commandbillPitems = new ArrayList<MesCommandbillPitem>();
                        List<MesCourseScanLog> courseScanLogs = new ArrayList<MesCourseScanLog>();
                        //消耗数量不超过上料数量的时候修改上料
                        for (MesCommandbillPitem commandbillPitem2 : commandbillPitemList) {

                            if (StringUtils.isBlank(commandbillPitem2.getConsumeNum())) {
                                commandbillPitem2.setConsumeNum("0");
                            }
                            BigDecimal consumeNum2 = new BigDecimal(commandbillPitem2.getConsumeNum());//已消耗数量
                            BigDecimal quantity2 = BigDecimal.ZERO;//消耗用量

                            //如果是反面的话
                            if ("反面".equals(mesCourseScan.getQuery3())) {
                                //根据bom去查反面用量，反面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getInverseQuantity())) {
                                    quantity2 = new BigDecimal(getsfg.getInverseQuantity().trim());
                                }
                            } else {
                                //据bom去查正面用量，正面用量为0就不扣
                                MesChiefdataBomitem getsfg = systemClient.getsfg(commandbillInfo.getMechanismCode(), commandbillPitem2.getMaterielCode());
                                if (getsfg != null && StringUtils.isNotBlank(getsfg.getQuantity().trim())) {
                                    quantity2 = new BigDecimal(getsfg.getQuantity());
                                }
                            }
                            //用量0跳出循环
                            if (quantity2.equals(BigDecimal.ZERO)) {
                                continue;
                            }
                            String itemid = commandbillPitem2.getId();
                            //过滤其中的上料信息
                            List<MesStorageWholesale> mesStorageWholesaleStream = mesStorageWholesales.stream().filter(f -> f.getBaseCode().equals(itemid)).collect(Collectors.toList());
//                            System.out.println("物料：" + commandbillPitem2.getMaterielCode());
//                            mesStorageWholesaleStream.forEach(System.out::println);
                            if (mesStorageWholesaleStream.size() == 0) {
                                throw new RuntimeException("未找到料号:" + commandbillPitem2.getMaterielCode() + " 的上料信息，请检查！");
                            }

                            BigDecimal sjnum = lbsnum.multiply(quantity2);//实际使用数量=连板数*消耗用量
                            BigDecimal totalNum2 = consumeNum2.add(sjnum);//新的消耗数量 = 已消耗数量 + 实际使用数量
                            if (totalNum2.compareTo(consumeNum2) == -1) {
                                throw new RuntimeException("消耗数量超过上料数量！请检查！");
                            }

                            //修改消耗数量
                            commandbillPitem2.setConsumeNum(totalNum2.toString());
//                            mesCommandbillPitemService.updateById(commandbillPitem2);
                            commandbillPitems.add(commandbillPitem2);
                            //判定当前使用的是哪个物料
                            Map<String, String> map = getwl(commandbillPitem2, mesStorageWholesaleStream);

                            //新增物料追踪记录，便于后期扫码追踪
                            MesCourseScanLog mesCourseScanLog = new MesCourseScanLog();
                            mesCourseScanLog.setCommandbillId(commandbillPitem2.getCommandbillId());
                            mesCourseScanLog.setCommandbillCode(commandbillPitem2.getCommandbillCode());
                            mesCourseScanLog.setFeederSn(map.get("feederSn"));
                            mesCourseScanLog.setPassage(map.get("passage"));
                            mesCourseScanLog.setStorageId(map.get("glazeId"));
                            mesCourseScanLog.setUnit(map.get("unit"));
                            mesCourseScanLog.setWareCode(map.get("wareCode"));
                            mesCourseScanLog.setWareName(map.get("wareName"));
                            mesCourseScanLog.setWareSite(map.get("wareSite"));
                            mesCourseScanLog.setLineType(commandbillInfo.getLineType());
                            mesCourseScanLog.setQuantity(commandbillPitem2.getQuantity());
                            mesCourseScanLog.setMaterielId(commandbillPitem2.getMaterielId());
                            mesCourseScanLog.setMaterielName(commandbillPitem2.getMaterielName());
                            mesCourseScanLog.setMaterielCode(commandbillPitem2.getMaterielCode());
                            mesCourseScanLog.setPcbId(scanContent);//pcbId
                            courseScanLogs.add(mesCourseScanLog);

                            //飞达使用次数增加
                            if (!"无feeder".equals(map.get("feederSn")) && !(sjnum.compareTo(BigDecimal.ZERO) == 0)) {
                                boolean mark = systemClient.editfeederComitem(map.get("feederSn"), sjnum.toString());
                                System.out.println("feedersn:" + map.get("feederSn") + " sjnum:" + sjnum.toString() + " 状态：" + mark);
                            }
                        }
                        //有这个bom的情况下新增线程扫描
                        mesCourseScan.setBatchNum(lbsnum.toString());
                        this.save(mesCourseScan);
                        //批量修改消耗数据
                        mesCommandbillPitemService.updateBatchById(commandbillPitems);
                        //批量新增物料追踪记录
                        mesCourseScanLogService.saveBatch(courseScanLogs);
                        //增加钢网刮刀使用次数
                        systemClient.increaseSteelmeshNum(ifbindgwSn);
                        systemClient.increaseScraperNum(ifbindgdSn);
                    }
                }
            }
        }
    }

    public MesMaterielPcb selectByMaterielPcb(String materielCode) {
        List<MesMaterielPcb> mesMaterielPcbList = systemClient.selectByMaterielPcb(materielCode);
        if (mesMaterielPcbList.size() > 0) {
            return mesMaterielPcbList.get(0);
        } else {
            throw new RuntimeException("PCB板没配置连扳数！请去物料管理配置该PCB板连扳数！");
        }
    }

    /**
     * 判定当前使用的是哪个物料
     *
     * @param commandbillPitem     物料bom信息
     * @param mesStorageWholesales 上料信息
     * @return
     */
    public Map<String, String> getwl(MesCommandbillPitem commandbillPitem, List<MesStorageWholesale> mesStorageWholesales) {
        Map<String, String> map = new ConcurrentHashMap<>();
        System.out.println("commandbillPitem:" + commandbillPitem);

        String feedersn = "无feeder";
        String passage = "无通道";
//		System.out.println("feedersn:"+feedersn+" passage:"+passage);
        //获取最后一个物料的feeder和通道
        //根据bom的消耗数量来判定是哪一个物料
        BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
        BigDecimal inwareNum = BigDecimal.ZERO;

//		System.out.println("已消耗数量: "+consumeNum);
//		System.out.println("扫描上料 批号交易查询数量: "+mesStorageWholesales.size());

        int iii = 0;//进去一次就不能继续往下添加的判定
        for (int i = 0; i < mesStorageWholesales.size(); i++) {
            MesStorageWholesale saleinfo = mesStorageWholesales.get(i);
            //MesStorageWholesale byinfo = stockClient.findById(saleinfo.getGlazeId());//二维码id查询该条数据获取数量
//			System.out.println("入库数量: "+i+": "+byinfo.getInwareNum());
            inwareNum = inwareNum.add(new BigDecimal(saleinfo.getInwareNum()));//每次都加上入库数量 需要跟据扫描上料的数量扣，应为可能会存在转产的情况

            if (consumeNum.compareTo(inwareNum) < 1 && iii == 0) {//consumeNum小于等于inwareNum
                iii = 1;
                if (StringUtils.isNotBlank(saleinfo.getQuery2()) && saleinfo.getQuery2().contains("feeder")) {
                    feedersn = saleinfo.getQuery2();
                    feedersn = feedersn.replace("feeder: ", "");
                }
                if (StringUtils.isNotBlank(saleinfo.getWareSite()) && saleinfo.getWareSite().contains("通道")) {
                    passage = saleinfo.getWareSite();
                    passage = passage.replace("通道: ", "");
                }
                map.put("glazeId", saleinfo.getGlazeId());
                if (StringUtils.isBlank(saleinfo.getUnit())) {
                    saleinfo.setUnit("");
                }
                map.put("unit", saleinfo.getUnit());
                if (StringUtils.isBlank(saleinfo.getQuery3())) {
                    saleinfo.setQuery3("");
                }
                map.put("wareCode", saleinfo.getQuery3());
                if (StringUtils.isBlank(saleinfo.getQuery4())) {
                    saleinfo.setQuery4("");
                }
                map.put("wareName", saleinfo.getQuery4());

                if (StringUtils.isBlank(saleinfo.getQuery5())) {
                    saleinfo.setQuery5("");
                }
                map.put("wareSite", saleinfo.getQuery5());
            }
        }

        map.put("feederSn", feedersn);
        map.put("passage", passage);

        return map;

    }
}
